package com.satalyst.webtest.model.page;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * A {@see PageGroup} provides a mechanism for grouping similar {@see Page} instances together. As well as this
 * @author Aidan Morgan
 */
public class PageGroup {
    private UUID id;
    private String name;
    private List<Page> pages;
    private List<PageGroup> childGroups;
    private PageGroup parentGroup;

    public PageGroup() {
        this(UUID.randomUUID(), "Unnamed Group");
    }

    public PageGroup(UUID id, String name) {
        this.id = id;
        this.name = name;

        this.pages = new ArrayList<Page>();
        this.childGroups = new ArrayList<PageGroup>();
    }

    public UUID getId() {
        return id;
    }

    public void setId(UUID id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Page> getPages() {
        return pages;
    }

    public List<PageGroup> getChildGroups() {
        return Collections.unmodifiableList(childGroups);
    }

    public void addGroup(PageGroup pc) {
        if (pc == null) {
            throw new IllegalArgumentException("Cannot add a null PageGroup as a child of PageGroup.");
        }

        // implement a "move" feature by making sure that if the incoming PageGroup already has an owner
        // that we remove it first.
        if (pc.getParentGroup() != null) {
            PageGroup parent = pc.getParentGroup();
            parent.removeGroup(pc);
        }

        if (!childGroups.contains(pc)) {
            childGroups.add(pc);
            pc.setParentGroup(this);
        }
    }

    public void removeGroup(PageGroup pc) {
        if (pc == null) {
            throw new IllegalArgumentException("Cannot remove a null PageGroup.");
        }

        if (pc.getParentGroup() == null) {
            throw new IllegalArgumentException("Cannot remove a top-level group.");
        }

        if (!childGroups.contains(pc)) {
            throw new IllegalArgumentException("This PageGroup does not own the provided PageGroup, cannot remove.");
        }

        childGroups.remove(pc);
        pc.setParentGroup(null);
    }

    public PageGroup getParentGroup() {
        return parentGroup;
    }

    protected void setParentGroup(PageGroup group) {
        this.parentGroup = group;
    }
}
